home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / dflat8.zip / MENUBAR.C < prev    next >
Text File  |  1991-09-30  |  9KB  |  373 lines

  1. /* ---------------- menubar.c -------------- */
  2.  
  3. #include "dflat.h"
  4.  
  5. static void reset_menubar(WINDOW);
  6.  
  7. static struct {
  8.     int x1, x2;        /* position in menu bar */
  9.     char sc;        /* shortcut key value   */
  10. } menu[10];
  11. static int mctr;
  12.  
  13. MBAR *ActiveMenuBar;
  14. static MENU *ActiveMenu;
  15.  
  16. static WINDOW mwnd;
  17. static int Selecting;
  18.  
  19. static WINDOW Cascaders[MAXCASCADES];
  20. static int casc;
  21. static WINDOW GetDocFocus(WINDOW);
  22.  
  23. static void SetFocusMsg(WINDOW wnd, PARAM p1)
  24. {
  25.     if ((int) p1)    {
  26.         if (ActiveMenuBar->ActiveSelection == -1)
  27.             ActiveMenuBar->ActiveSelection = 0;
  28.         if (inFocus == wnd)
  29.             SendMessage(wnd, PAINT, 0, 0);
  30.     }
  31.     else    {
  32.         SendMessage(wnd, PAINT, 0, 0);
  33.         SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
  34.     }
  35. }
  36.  
  37. static void CommandMsg(WINDOW wnd, PARAM p1, PARAM p2)
  38. {
  39.     if (isCascadedCommand(ActiveMenuBar, (int)p1))    {
  40.         /* find the cascaded menu based on command id in p1 */
  41.         MENU *mnu = ActiveMenu+mctr;
  42.         while (mnu->Title != (void *)-1)    {
  43.             if (mnu->CascadeId == (int) p1)    {
  44.                 if (casc < MAXCASCADES)    {
  45.                     Cascaders[casc++] = mwnd;
  46.                     SendMessage(wnd, SELECTION,
  47.                         (PARAM)(mnu-ActiveMenu), TRUE);
  48.                 }
  49.                 break;
  50.             }
  51.             mnu++;
  52.         }
  53.     }
  54.     else     {
  55.         if (mwnd != NULL)
  56.             SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  57.         SendMessage(GetDocFocus(wnd), SETFOCUS, TRUE, 0);
  58.         PostMessage(GetParent(wnd), COMMAND, p1, p2);
  59.     }
  60. }
  61.  
  62. static void BuildMenuMsg(WINDOW wnd, PARAM p1)
  63. {
  64.     int offset = 3;
  65.     reset_menubar(wnd);
  66.     mctr = 0;
  67.     ActiveMenuBar = (MBAR *) p1;
  68.     ActiveMenu = ActiveMenuBar->PullDown;
  69.     while (ActiveMenu->Title != NULL && ActiveMenu->Title != (void*)-1)    {
  70.         char *cp;
  71.         if (strlen(GetText(wnd)+offset) < strlen(ActiveMenu->Title)+3)
  72.             break;
  73.         GetText(wnd) = realloc(GetText(wnd), strlen(GetText(wnd))+5);
  74.         memmove(GetText(wnd) + offset+4, GetText(wnd) + offset,
  75.                 strlen(GetText(wnd))-offset+1);
  76.         CopyCommand(GetText(wnd)+offset, ActiveMenu->Title, FALSE,
  77.                 wnd->WindowColors [STD_COLOR] [BG]);
  78.         menu[mctr].x1 = offset;
  79.         offset += strlen(ActiveMenu->Title) + (3+MSPACE);
  80.         menu[mctr].x2 = offset-MSPACE;
  81.         cp = strchr(ActiveMenu->Title, SHORTCUTCHAR);
  82.         if (cp)
  83.             menu[mctr].sc = tolower(*(cp+1));
  84.         mctr++;
  85.         ActiveMenu++;
  86.     }
  87.     ActiveMenu = ActiveMenuBar->PullDown;
  88. }
  89.  
  90. static void PaintMsg(WINDOW wnd)
  91. {
  92.     if (wnd == inFocus)
  93.         SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
  94.     SetStandardColor(wnd);
  95.     wputs(wnd, GetText(wnd), 0, 0);
  96.     if (ActiveMenuBar->ActiveSelection != -1 &&
  97.             (wnd == inFocus || mwnd != NULL))    {
  98.         char *sel;
  99.         char *cp;
  100.         if ((sel = malloc(200)) != NULL)    {
  101.             int offset = menu[ActiveMenuBar->ActiveSelection].x1;
  102.             int offset1 = menu[ActiveMenuBar->ActiveSelection].x2;
  103.             GetText(wnd)[offset1] = '\0';
  104.             SetReverseColor(wnd);
  105.             memset(sel, '\0', 200);
  106.             strcpy(sel, GetText(wnd)+offset);
  107.             cp = strchr(sel, CHANGECOLOR);
  108.             if (cp != NULL)
  109.                 *(cp + 2) = background | 0x80;
  110.             wputs(wnd, sel, offset-ActiveMenuBar->ActiveSelection*4, 0);
  111.             GetText(wnd)[offset1] = ' ';
  112.             if (!Selecting && mwnd == NULL && wnd == inFocus)    {
  113.                 char *st = ActiveMenu[ActiveMenuBar->ActiveSelection].StatusText;
  114.                 if (st != NULL)
  115.                     SendMessage(GetParent(wnd), ADDSTATUS, (PARAM)st, 0);
  116.             }
  117.             free(sel);
  118.         }
  119.     }
  120. }
  121.  
  122. static void KeyboardMsg(WINDOW wnd, PARAM p1)
  123. {
  124.     MENU *mnu;
  125.     if (mwnd == NULL)    {
  126.         /* ----- search for menu bar shortcut keys ---- */
  127.         int c = tolower((int)p1);
  128.         int a = AltConvert((int)p1);
  129.         int j;
  130.         for (j = 0; j < mctr; j++)    {
  131.             if ((inFocus == wnd && menu[j].sc == c) ||
  132.                     (a && menu[j].sc == a))    {
  133.                 SendMessage(wnd, SELECTION, j, 0);
  134.                 return;
  135.             }
  136.         }
  137.     }
  138.     /* -------- search for accelerator keys -------- */
  139.     mnu = ActiveMenu;
  140.     while (mnu->Title != NULL)    {
  141.         struct PopDown *pd = mnu->Selections;
  142.         if (mnu->PrepMenu)
  143.             (*(mnu->PrepMenu))(GetDocFocus(wnd), mnu);
  144.         while (pd->SelectionTitle != NULL)    {
  145.             if (pd->Accelerator == (int) p1)    {
  146.                 if (pd->Attrib & INACTIVE)
  147.                     beep();
  148.                 else    {
  149.                     if (pd->Attrib & TOGGLE)
  150.                         pd->Attrib ^= CHECKED;
  151.                     SendMessage(GetDocFocus(wnd), SETFOCUS, TRUE, 0);
  152.                     PostMessage(GetParent(wnd),
  153.                         COMMAND, pd->ActionId, 0);
  154.                 }
  155.                 return;
  156.             }
  157.             pd++;
  158.         }
  159.         mnu++;
  160.     }
  161.     switch ((int)p1)    {
  162.         case F1:
  163.             if (ActiveMenu != NULL &&
  164.                 (mwnd == NULL ||
  165.                 (ActiveMenu+ActiveMenuBar->ActiveSelection)->
  166.                     Selections[0].SelectionTitle == NULL)) {
  167.                 DisplayHelp(wnd, (ActiveMenu+ActiveMenuBar->ActiveSelection)->Title+1);
  168.                 return;
  169.             }
  170.             break;
  171.         case '\r':
  172.             if (mwnd == NULL && ActiveMenuBar->ActiveSelection != -1)
  173.                 SendMessage(wnd, SELECTION, ActiveMenuBar->ActiveSelection, 0);
  174.             break;
  175.         case F10:
  176.             if (wnd != inFocus && mwnd == NULL)    {
  177.                 SendMessage(wnd, SETFOCUS, TRUE, 0);
  178.                 break;
  179.             }
  180.             /* ------- fall through ------- */
  181.         case ESC:
  182.             if (inFocus == wnd && mwnd == NULL)    {
  183.                 ActiveMenuBar->ActiveSelection = -1;
  184.                 SendMessage(GetDocFocus(wnd), SETFOCUS, TRUE, 0);
  185.                 SendMessage(wnd, PAINT, 0, 0);
  186.             }
  187.             break;
  188.         case FWD:
  189.             ActiveMenuBar->ActiveSelection++;
  190.             if (ActiveMenuBar->ActiveSelection == mctr)
  191.                 ActiveMenuBar->ActiveSelection = 0;
  192.             if (mwnd != NULL)
  193.                 SendMessage(wnd, SELECTION, ActiveMenuBar->ActiveSelection, 0);
  194.             else 
  195.                 SendMessage(wnd, PAINT, 0, 0);
  196.             break;
  197.         case BS:
  198.             if (ActiveMenuBar->ActiveSelection == 0)
  199.                 ActiveMenuBar->ActiveSelection = mctr;
  200.             --ActiveMenuBar->ActiveSelection;
  201.             if (mwnd != NULL)
  202.                 SendMessage(wnd, SELECTION, ActiveMenuBar->ActiveSelection, 0);
  203.             else 
  204.                 SendMessage(wnd, PAINT, 0, 0);
  205.             break;
  206.         default:
  207.             break;
  208.     }
  209. }
  210.  
  211. static void LeftButtonMsg(WINDOW wnd, PARAM p1)
  212. {
  213.     int i = BarSelection((int) p1 - GetLeft(wnd));
  214.     if (i < mctr)
  215.         if (i != ActiveMenuBar->ActiveSelection || mwnd == NULL)
  216.             SendMessage(wnd, SELECTION, i, 0);
  217. }
  218.  
  219. static void SelectionMsg(WINDOW wnd, PARAM p1, PARAM p2)
  220. {
  221.     int offset = 3, wd, mx, my;
  222.     MENU *mnu;
  223.  
  224.     Selecting = TRUE;
  225.     mnu = ActiveMenu+(int)p1;
  226.     if (mnu->PrepMenu != NULL)
  227.         (*(mnu->PrepMenu))(GetDocFocus(wnd), mnu);
  228.     wd = MenuWidth(mnu->Selections);
  229.     if (p2)    {
  230.         mx = GetLeft(inFocus) +    WindowWidth(inFocus) - 1;
  231.         my = GetTop(inFocus) + inFocus->selection;
  232.     }
  233.     else    {
  234.         if (mwnd != NULL)    {
  235.             SendMessage(wnd, SETFOCUS, TRUE, 0);
  236.             SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  237.         }
  238.         ActiveMenuBar->ActiveSelection = (int) p1;
  239.         offset = menu[ActiveMenuBar->ActiveSelection].x1 -
  240.                     4 * ActiveMenuBar->ActiveSelection;
  241.         if (offset > WindowWidth(wnd)-wd)
  242.             offset = WindowWidth(wnd)-wd;
  243.         mx = GetLeft(wnd)+offset;
  244.         my = GetTop(wnd)+1;
  245.     }
  246.     mwnd = CreateWindow(POPDOWNMENU, NULL,
  247.                 mx, my,
  248.                 MenuHeight(mnu->Selections),
  249.                 wd,
  250.                 NULL,
  251.                 wnd,
  252.                 NULL,
  253.                 0);
  254.     AddAttribute(mwnd, SHADOW);
  255.     if (mnu->Selections[0].SelectionTitle != NULL)    {
  256.         SendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0);
  257.         SendMessage(mwnd, SETFOCUS, TRUE, 0);
  258.     }
  259.     else
  260.         SendMessage(wnd, PAINT, 0, 0);
  261.     Selecting = FALSE;
  262. }
  263.  
  264. static void ClosePopdownMsg(WINDOW wnd, PARAM p1)
  265. {
  266.     if (casc > 0)
  267.         SendMessage(Cascaders[--casc], CLOSE_WINDOW, p1, 0);
  268.     else     {
  269.         mwnd = NULL;
  270.         ActiveMenuBar->ActiveSelection = -1;
  271.         if (!Selecting)
  272.             SendMessage(GetDocFocus(wnd), SETFOCUS, TRUE, 0);
  273.         SendMessage(wnd, PAINT, 0, 0);
  274.     }
  275. }
  276.  
  277. static void CloseWindowMsg(WINDOW wnd)
  278. {
  279.     if (GetText(wnd) != NULL)    {
  280.         free(GetText(wnd));
  281.         GetText(wnd) = NULL;
  282.     }
  283.     mctr = 0;
  284.     ActiveMenuBar->ActiveSelection = -1;
  285.     ActiveMenu = NULL;
  286.     ActiveMenuBar = NULL;
  287. }
  288.     
  289. int MenuBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  290. {
  291.     int rtn;
  292.  
  293.     switch (msg)    {
  294.         case CREATE_WINDOW:
  295.             reset_menubar(wnd);
  296.             break;
  297.         case SETFOCUS:
  298.             rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  299.             SetFocusMsg(wnd, p1);
  300.             return rtn;
  301.         case COMMAND:
  302.             CommandMsg(wnd, p1, p2);
  303.             return TRUE;
  304.         case BUILDMENU:
  305.             BuildMenuMsg(wnd, p1);
  306.             break;
  307.         case PAINT:    
  308.             if (!isVisible(wnd) || GetText(wnd) == NULL)
  309.                 break;
  310.             PaintMsg(wnd);
  311.             return FALSE;
  312.         case KEYBOARD:
  313.             KeyboardMsg(wnd, p1);
  314.             return TRUE;
  315.         case LEFT_BUTTON:
  316.             LeftButtonMsg(wnd, p1);
  317.             return TRUE;
  318.         case SELECTION:
  319.             SelectionMsg(wnd, p1, p2);
  320.             break;
  321.         case BORDER:
  322.             return TRUE;
  323.         case INSIDE_WINDOW:
  324.             return InsideRect(p1, p2, WindowRect(wnd));
  325.         case CLOSE_POPDOWN:
  326.             ClosePopdownMsg(wnd, p1);
  327.             return TRUE;
  328.         case CLOSE_WINDOW:
  329.             rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  330.             CloseWindowMsg(wnd);
  331.             return rtn;
  332.         default:
  333.             break;
  334.     }
  335.     return BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  336. }
  337.  
  338. static WINDOW GetDocFocus(WINDOW wnd)
  339. {
  340.     WINDOW DocFocus = Focus.LastWindow;
  341.     CLASS cl;
  342.     while ((cl = GetClass(DocFocus)) == MENUBAR ||
  343.                 cl == POPDOWNMENU ||
  344.                     cl == STATUSBAR ||
  345.                         cl == APPLICATION)                    {
  346.         if ((DocFocus = PrevWindow(DocFocus)) == NULL)    {
  347.             DocFocus = GetParent(wnd);
  348.             break;
  349.         }
  350.     }
  351.     return DocFocus;
  352. }
  353.  
  354. static void reset_menubar(WINDOW wnd)
  355. {
  356.     if ((GetText(wnd) = realloc(GetText(wnd), SCREENWIDTH+5)) != NULL)    {
  357.         memset(GetText(wnd), ' ', SCREENWIDTH);
  358.         *(GetText(wnd)+WindowWidth(wnd)) = '\0';
  359.     }
  360. }
  361.  
  362. int BarSelection(int mx)
  363. {
  364.     int i;
  365.     for (i = 0; i < mctr; i++)
  366.         if (mx >= menu[i].x1-4*i &&
  367.                 mx <= menu[i].x2-4*i-5)
  368.             break;
  369.     return i;
  370. }
  371.  
  372.  
  373.